home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / GRAPHICS / ZBUFER.ZIP / ZBUFER.TXT
Encoding:
Text File  |  1996-04-26  |  27.2 KB  |  1,093 lines

  1. ┌──────────────────────────────────────────────────────────────────────────────┐
  2.  
  3. │       Previous notes:                                                        │
  4.  
  5. │       -The author assume no responsability for any effects/damage            │
  6.  
  7. │        this file can produce.                                                │
  8.  
  9. │       -This file cannot be modified without the author's permission.         │
  10.  
  11. │       -This file can be (and must be !) freely distributed                   │
  12.  
  13. └──────────────────────────────────────────────────────────────────────────────┘
  14.  
  15.  
  16.  
  17. ================================================================================
  18.  
  19.         MORE ABOUT SHADING, Z-BUFFER, AND TEXTURES
  20.  
  21. ================================================================================
  22.  
  23.  
  24.  
  25.         I heard not so long ago talking about method of shading called
  26.  
  27.         Gouraud shading, mainly based on the interpolation of the
  28.  
  29.         light intensity along the edge of the polygon and then along
  30.  
  31.         each scanline of it.
  32.  
  33.         The book in wich I read it was saying: "very approximative but
  34.  
  35.         very fast, this method is often used in real-time applications,
  36.  
  37.         because of its low cost in calculation time"(or sumthin like that..).
  38.  
  39.         After, I've seen it in many demos, and didn't understand how
  40.  
  41.         a so slow and uncomfortable algorithm could be used for animating
  42.  
  43.         thousand of vectors at a reasonnable frame-rate on my computer.
  44.  
  45.         It's only a few months ago I realized how fast and comfortable
  46.  
  47.         This method was and how many doors in the domain of 3d animation
  48.  
  49.         it opened to me.
  50.  
  51.         It's the principle of interpolating values along a polygon using
  52.  
  53.         fixed point math that is the key of many other algorithms,
  54.  
  55.         such as:
  56.  
  57.                 - the degenerated Gouraud's: Z-gouraud, distance-based Gouraud
  58.  
  59.                 - Phong shading
  60.  
  61.                 - Z-buffer
  62.  
  63.                 - texture mapping
  64.  
  65.                 - many other more advanced techniques like:
  66.  
  67.                         - environment/reflection mapping
  68.  
  69.                         - bump mapping
  70.  
  71.                         - A-buffer
  72.  
  73.                 - and much more I expect you'll find and write to me !..
  74.  
  75.  
  76.        ┌───────────────────────────────────┐
  77.  
  78.        │1) The first step: Gouraud shading │
  79.  
  80.        └───────────────────────────────────┘
  81.  
  82.  
  83.         I won't repeat here what many other docs already told,
  84.  
  85.         but just make a brief recapitulation.
  86.  
  87.         Here's your polygon:
  88.  
  89.  
  90.                   I ->          * At each vertice constituing the poly,
  91.  
  92.                   I N1          you can compute a normal vector,
  93.  
  94.                  /\             (preferably precalculated and rotated
  95.  
  96.                 /  \            like the other vertices).
  97.  
  98.                /    \           using this normal vector, you can
  99.  
  100.               /      \--->      find the light intensity, which is
  101.  
  102.              /       /->        simply the cosine of the angle between
  103.  
  104.         <---/       / N2        the normal vector and the light vector,
  105.  
  106.         ->  \      /            given by:
  107.  
  108.         N4   \    /                       ->  ->
  109.  
  110.               \  /               cos a = (N . L)/[L]*[N]
  111.  
  112.                \/
  113.  
  114.                I                where N and L are respectively the
  115.  
  116.                I                normal and the light vector and
  117.  
  118.                I ->             [N] and [L] are the length of these two
  119.  
  120.                v N3             vectors.
  121.  
  122.  
  123.         It's obvious that these two lengths should value 1.
  124.  
  125.         The intensity is then just the dot product of the two vectors.
  126.  
  127.  
  128.         * The next step is to know, or just approximate, the intensity
  129.  
  130.         at each point of the poly. to do this, just IN-TER-PO-LA-TE !!
  131.  
  132.         For example: we just compute the intensity at each point of the
  133.  
  134.         poly nicely drawed above, you got for ex. the values a1 and a2
  135.  
  136.         corresponding to the two vectors N1 and N2.
  137.  
  138.         The value of the intensity at the point x,y of the first right
  139.  
  140.         edge is given by:
  141.  
  142.  
  143.                          a = a1 + (y - y1)*((a2 - a1)/(y2 - y1))
  144.  
  145.  
  146.         where a1 and a2 are the intensity of the points 1 and 2
  147.  
  148.               y1 and y2 are the y-coord ON THE SCREEN of these two points.
  149.  
  150.  
  151.         You got now all the values of the intensity along each edge
  152.  
  153.         of the poly. the second part of the algorithm concern
  154.  
  155.         the interpolation of these values along each scanline
  156.  
  157.         of the poly, thus obtaining the intensity at each pixel...
  158.  
  159.         This is done using the same scheme:
  160.  
  161.  
  162.                          a = a1 + (x - x1)*((a2 - a1)/(x2 - x1))
  163.  
  164.  
  165.         where a1 and a2 are the intensity of the points 1 and 2
  166.  
  167.               x1 and x2 are the x-coord   "    "        "     "
  168.  
  169.  
  170.  
  171.                           /\
  172.  
  173.                          /  \
  174.  
  175.                         /    \
  176.  
  177.                        /      \
  178.  
  179.                       /        \
  180.  
  181.                    a1<__________>a2   <--- scanline
  182.  
  183.                     /    <--a--> \
  184.  
  185.                    /              \
  186.  
  187.                   /                \
  188.  
  189.                  /                  \
  190.  
  191.                  \                  /
  192.  
  193.                   \                /
  194.  
  195.                    \              /
  196.  
  197.                     \            /
  198.  
  199.                      \          /
  200.  
  201.                       \        /
  202.  
  203.                        \      /
  204.  
  205.                         \    /
  206.  
  207.                          \  /
  208.  
  209.                           \/
  210.  
  211.  
  212.  
  213.         Of coz it shouldn't be done using one MUL and one DIV per
  214.  
  215.         pixel ! The values (for ex. in the last formula) :
  216.  
  217.             (a2-a1) and (x2-x1) are precalculated for each scanline,
  218.  
  219.             and so is the value (a2-a1)/(x2-x1)...
  220.  
  221.         Then you set the first 'a' at the value a1 and the only
  222.  
  223.         operation you'll have to do for each pixel is just an addition
  224.  
  225.         between two fixed-point values. (a and (a2-a1)/(x2-x1))
  226.  
  227.  
  228.         A brief example for the implementation :
  229.  
  230.             for each point of the scanline do:
  231.  
  232.  
  233.             {asm code}              {pseudo-code}
  234.  
  235.  
  236.             MOV     AL,DH       ; al = a shr 8
  237.  
  238.             ADD     DX,BP       ; a = a+((a2-a1)/(x2-x1))
  239.  
  240.             STOSB               ; es:[di] = a ; di = di+1
  241.  
  242.  
  243.  
  244.  
  245.         'GoT It ??
  246.  
  247.  
  248.        ┌──────────────────────────────────────────┐
  249.  
  250.        │2) The next step : Z-Gouraud and Z-buffer │
  251.  
  252.        └──────────────────────────────────────────┘
  253.  
  254.  
  255.         So now you got the code (how that 'not yet !!' ??) for
  256.  
  257.         interpolate one single value along a polygon.
  258.  
  259.  
  260.         you can interpolate this famous intensity, as in the
  261.  
  262.         most classic Gourauds, but there is much more amusing:
  263.  
  264.         just approximate the Z component of each point of the
  265.  
  266.         polygon, using the same method.
  267.  
  268.  
  269.         If you plot the intensity corresponding to this value
  270.  
  271.         you'll have some kind of 'depth shading' effect.
  272.  
  273.         (also known as 'Z-Gouraud', which is quite comprehensible!)
  274.  
  275.  
  276.         Having the Z component of each point is very interesting
  277.  
  278.         when you have two faces intersecting each other.
  279.  
  280.         (f.e. when two objx are colliding !..)
  281.  
  282.  
  283.         Just set up a huge (320*200 is good) buffer in your mem, where
  284.  
  285.         you put the Z-value of every pixel on the screen.
  286.  
  287.         when you try to write a pixel, first ask yourself:
  288.  
  289.             'ain't there any point recovering the one I wanna write ?'
  290.  
  291.         In computer language, this is called a 'test'!:
  292.  
  293.         It just means : look if the Z-value of the current point
  294.  
  295.         is greater than the corresponding value in the Z_buffer.
  296.  
  297.         If it is, don't write it ! if not, you can write it
  298.  
  299.         on the screen (or in a screen-equivalent buffer..) and
  300.  
  301.         write its Z value in the Z-buffer !
  302.  
  303.  
  304.         This method is -let's be reasonnable- very slow, it means
  305.  
  306.         one test per pixel, plus the refreshment of the Z_buffer
  307.  
  308.         (all points should be set to (-infiny) at every frame !),
  309.  
  310.         and a writing operation two times slower than the Gouraud
  311.  
  312.         shading one...
  313.  
  314.         But it is also the most realistic and impressive method
  315.  
  316.         for intersecting objects, Z-clipping (which can be done
  317.  
  318.         automatically using an unsigned test..),it allows
  319.  
  320.         immediate depth-shading, etc...
  321.  
  322.  
  323.         If you didn't understood everything, these littal schemas
  324.  
  325.         are gonna help you:
  326.  
  327.  
  328.         Z-buff:                  screen:
  329.  
  330.  
  331.         ┌────────────┐           ┌────────────┐
  332.  
  333.         │            │           │            │   ░ poly #1
  334.  
  335.         │            │           │            │
  336.  
  337.         │  1111      │           │  ░░░░      │   ▒ poly #2
  338.  
  339.         │ 2222       │           │ ░░░░       │
  340.  
  341.         │334444      │           │░░▒▒▒▒      │   █ poly #3
  342.  
  343.         │   5555     │           │   ▒▒▒▒     │
  344.  
  345.         │ 2366766    │           │ ██▒▒█▒▒    │
  346.  
  347.         │ 23457      │           │ █████      │
  348.  
  349.         │ 23457      │           │ █████      │
  350.  
  351.         │ 23457      │           │ █████      │
  352.  
  353.         │ 23457      │           │ █████      │
  354.  
  355.         └────────────┘           └────────────┘
  356.  
  357.  
  358.         The poly #3 is intersecting the poly #2, which is itself
  359.  
  360.         recovering the poly #1...
  361.  
  362.  
  363.         WARNING !!  these drawings assume that the Z-axis is
  364.  
  365.                     pointing towards the observer.
  366.  
  367.                     (the greater is the nearer..)
  368.  
  369.  
  370.         And of coz, again a tiny example of the main loop
  371.  
  372.         implementation: (the rasterizer)
  373.  
  374.         (in 386 assembler, quite more easy than 8088..)
  375.  
  376.  
  377.         @@:
  378.  
  379.             SHRD    EBX,EDX,24          ; ebx = edx shr 8
  380.  
  381.             ADD     EDX,EBP             ; compute the Z value
  382.  
  383.             CMP     BX,Z_BUFF[EDI*2]    ; Z > z_buff[di] ??
  384.  
  385.             JG      PLOT_IT             ; yes ..
  386.  
  387.             INC     EDI                 ; no: nothing
  388.  
  389.             LOOP    @B
  390.  
  391.  
  392.             JMP     @F
  393.  
  394.  
  395.         PLOT_IT:
  396.  
  397.             MOV     SCREEN[EDI],AL      ; store the color..
  398.  
  399.             MOV     Z_BUFF[EDI*2],BX    ; store the Z-value
  400.  
  401.             INC     EDI                 ; next one!...
  402.  
  403.             LOOP    @B
  404.  
  405.  
  406.         @@:
  407.  
  408.  
  409.         Again, don't forget to reverse the test if you are using another
  410.  
  411.         orientation..
  412.  
  413.  
  414.        ┌────────────┐
  415.  
  416.        │3) Textures │
  417.  
  418.        └────────────┘
  419.  
  420.  
  421.         So now you passed two months trying to understand this shit,
  422.  
  423.         you got it, nicely shaded polys rotating around each other and
  424.  
  425.         intersecting,and so on...
  426.  
  427.         But what about mapping?
  428.  
  429.         It just means put a bitmap onto a polygon, just as if
  430.  
  431.         the bitmap was itself rotating in the space.
  432.  
  433.         (I'm sure you've already seen that somewhere...)
  434.  
  435.  
  436.         How to do it?
  437.  
  438.         we'll pass over the boring 'it's-not-possible-to-do-free-direction-
  439.  
  440.         texture-mapping-in-real-time-so-I'll-just-show-you-how-to-make-
  441.  
  442.         floors'
  443.  
  444.         real-time free direction texture-mapping IS possible and I'm
  445.  
  446.         gonna show you how...
  447.  
  448.  
  449.         You know how to interpolate one value along a polygon:
  450.  
  451.         free distorsion/linear mapping , which are the true names
  452.  
  453.         of the method I use,only consists in interpolating
  454.  
  455.         TWO values instead of one.
  456.  
  457.         These two values are just the coordinates (UVs or IJs) of the point in
  458.  
  459.         the texture-map corresponding to the point on the poly.
  460.  
  461.  
  462.         Well, just consider the poly we used in the Gouraud shading example:
  463.  
  464.  
  465. ┌───────────────────────────────────────────┬──────────────────────────────────┐
  466.  
  467. │                   iB,jB                   │                                  │
  468.  
  469. │                 /\                        │<--- on the screen, it looks like:│
  470.  
  471. │                /  \                       │                                  │
  472.  
  473. │               /    \                      ├──────────────────────────────────┤
  474.  
  475. │              /      \                     │                                  │
  476.  
  477. │       i1,j1 /        \ i2,j2              │                                  │
  478.  
  479. │            <---------->       <-- scanline│   in the texture, it looks like: │
  480.  
  481. │           /  <-i,j->   \                  ├──────────────────────────────────┤
  482.  
  483. │          /              \                 │                                  │
  484.  
  485. │         /                \                │               i1,j1              │
  486.  
  487. │        /                  \               │  iA,jA <-------+-----> iB,jB     │
  488.  
  489. │  iA,jA \                  /               │     ┌───────────\──────┐         │
  490.  
  491. │         \                /                │     │            \     │         │
  492.  
  493. │          \              /                 │     │  B   I  T  -\    │         │
  494.  
  495. │           \            /                  │     │              \   │         │
  496.  
  497. │            \          /                   │     │               \  │         │
  498.  
  499. │             \        /                    │     │    -  M  A  P  \ │         │
  500.  
  501. │              \      /                     │     │                 \+ i2,j2   │
  502.  
  503. │               \    /                      │     │                  │         │
  504.  
  505. │                \  /                       │     │                  │         │
  506.  
  507. │                 \/                        │     └──────────────────┘         │
  508.  
  509. │                                           │                                  │
  510.  
  511. │                                           │                                  │
  512.  
  513. │                                           │                                  │
  514.  
  515. └───────────────────────────────────────────┴──────────────────────────────────┘
  516.  
  517.  
  518.         As you can see, there are two interpolations, and, for each point, you
  519.  
  520.         got to find the offset corresponding to the two interpolated
  521.  
  522.         coordinates.
  523.  
  524.  
  525.         The pseudo-code looks like:
  526.  
  527.  
  528.         for each point on the scanline:
  529.  
  530.         {   i=i+inc_i ;
  531.  
  532.             j=j+inc_j ;
  533.  
  534.             c=texture[i,j] ;
  535.  
  536.             plot (c) ;
  537.  
  538.         }
  539.  
  540.  
  541.         The main difficulty is to code it in assembler, and using the less
  542.  
  543.         instructions as possible.
  544.  
  545.         I think it is possible to do it in six instructions per pixel.
  546.  
  547.         Has anybody got better ?
  548.  
  549.  
  550.         code sample:
  551.  
  552.         (assuming a 256*X bit-map)
  553.  
  554.         ; EDX and ESI     are the shifted coord.
  555.  
  556.         ; EBP and INC_J   are the corresponding shifted increments.
  557.  
  558.         ; ECX is the nb. of points on the scanline
  559.  
  560.         ; EDI is the offset in the screen
  561.  
  562.  
  563.         @@:
  564.  
  565.         MOV     BX,SI           ; bx <- l2 shl 8
  566.  
  567.         MOV     BL,DH           ; bx <- l2 shl 8 + l1
  568.  
  569.         MOV     AL,TEXTURE[BX]  ; get the pixel in the bitmap
  570.  
  571.         STOSB                   ; aff. le pixel
  572.  
  573.         ADD     EDX,EBP         ; incr. i
  574.  
  575.         ADD     ESI,INC_J       ; incr. j
  576.  
  577.         LOOP    @B
  578.  
  579.  
  580.         (I'll tell you later how to get rid of the 'INC_J' var...
  581.  
  582.         asm fans don't worry ! cf. tricks&tips: unrolled loops )
  583.  
  584.  
  585.         Well, OK, this is not true texture-mapping (As I said, this
  586.  
  587.         is only free-disto), but the illusion works, and the method
  588.  
  589.         is fast.
  590.  
  591.         (the game DESCENT implements true texture-mapping, if
  592.  
  593.         there is a guy somewhere who knows how: please tell me !!)
  594.  
  595.  
  596.        ┌──────────────────────────────┐
  597.  
  598.        │4) A word about Phong shading │
  599.  
  600.        └──────────────────────────────┘
  601.  
  602.  
  603.         Well, I ain't gonna give here THE method for Phong-shade
  604.  
  605.         your polys, I don't know wich is the fastest one, but
  606.  
  607.         I am able to tell you some tricks I collected here and there..
  608.  
  609.         (Usenet discussions,f.e..).
  610.  
  611.         First you should know that many Phong that you've seen in
  612.  
  613.         demos or other are fakes, I mean they are just modified
  614.  
  615.         Gouraud shading. We can demonstrate that with a sufficient amount
  616.  
  617.         of polygons and using the Phong illumination model
  618.  
  619.         ( the shadings in the palette are non-linear ), the differences
  620.  
  621.         between G-shading and P-shading are very small (but they do exist..).
  622.  
  623.  
  624.         The main principle is that instead of interpolating intensities, like
  625.  
  626.         in Gouraud, just interpolate normal vectors along your scanlines..
  627.  
  628.         It means three values to compute for every pixel (x,y and z coords).
  629.  
  630.         Then, when you've got your normal vector for each point, you gotta
  631.  
  632.         renormalise it,it means divide each coordinate by the current length
  633.  
  634.         of your interpolated vector. It must be done to compute properly the dot
  635.  
  636.         product between this vector and the light vector, then you've got your
  637.  
  638.         intensity !..
  639.  
  640.  
  641.         A little drawing ?:           x
  642.  
  643.                                      /  light src
  644.  
  645.                                     /
  646.  
  647.                                    /
  648.  
  649.  
  650.  
  651.                       ..... N ....
  652.  
  653.                  .....      :     ....
  654.  
  655.           N1  ...           :         ....  N2
  656.  
  657.             ................:...............
  658.  
  659.             \               I              /
  660.  
  661.              \              I             /
  662.  
  663.               \             I            /
  664.  
  665.                \____________I___________/
  666.  
  667.                                             <-- scanline
  668.  
  669.  
  670.         N1 and N2 are the start-and-end vectors,
  671.  
  672.         N is the interpolated vector,
  673.  
  674.         the part of the N vector in  ':' is the result of the renormalisation..
  675.  
  676.  
  677.         As you can expect, this is impossible to compute in real-time..
  678.  
  679.         (using this algorithm, I mean!..)
  680.  
  681.         you've got to update 3 values (the coordinates of the
  682.  
  683.         interpolated vector), find the length, divide
  684.  
  685.         the coords by this length and then compute a dot product...
  686.  
  687.         It takes something like 3 ADDs, 3 DIVs and 6 MULs per pixel !!
  688.  
  689.  
  690.         There are some speed-up tech.. I'm gonna make here a brief overview.
  691.  
  692.  
  693.         First: don't compute every pixel: you can easily display three
  694.  
  695.         pixels of the same color together, or better: compute the true
  696.  
  697.         values every 4 pixels and interpolate between them...
  698.  
  699.         (I already told ya: 'interpolation' is THE word..)
  700.  
  701.  
  702.         next: linear approximation is good, but quadratic is better !
  703.  
  704.         I've read a very interesting article in IMPHOBIA mag N°10,
  705.  
  706.         written by .. mhh .. don't remember .. (greetingz!),
  707.  
  708.         talking about QUAD-ADDERS : a very efficient method for
  709.  
  710.         interpolating between three values using a parabolic curve.
  711.  
  712.         It only takes 2 ADD's per pixel !
  713.  
  714.         you just have to compute three values on your scanline (with kewl
  715.  
  716.         MUL's and DIV's !!), and then interpolate (again!) between 'em.
  717.  
  718.         Just read this article, coz the development is too long for this txt...
  719.  
  720.  
  721.         another one: 'FAST PHONG' by Mister Bishop (??), using taylor
  722.  
  723.         approximations... I didn't read it. :/
  724.  
  725.         see ACM computer graphics 20(4) pp.103-106  '1986
  726.  
  727.  
  728.         Some other methods were developped, using angular or bi-angular
  729.  
  730.         interpolations.. (see f.e. 'faster Phong shading via angular interpo-
  731.  
  732.         -lation', Kujik & Blake, computer graphics forum 8 (1989)).
  733.  
  734.  
  735.         Also think about spherical coordinates and look-up tables.. ;)
  736.  
  737.  
  738.        ┌───────────────────┐
  739.  
  740.        │5) Tricks and tips │
  741.  
  742.        └───────────────────┘
  743.  
  744.  
  745.         a)- fixed-point maths
  746.  
  747.         ---------------------
  748.  
  749.  
  750.         For those who didn't understand how I was doing my incrementations,
  751.  
  752.         here's a brief recap of the fixed-point principle:
  753.  
  754.  
  755.         We assume the values you're computing are made of two parts:
  756.  
  757.         the integer part and the decimal part, the one after the point.
  758.  
  759.         these two parts are contained in one number and you can decide
  760.  
  761.         which bits are significant for the int. or dec. part.
  762.  
  763.         It's very easy to implement : You just have to shift your numbers
  764.  
  765.         of n bits, meaning you multiply them by 2^n. When you want your
  766.  
  767.         integer approx., just 'de-shift' them by the right number of bits.
  768.  
  769.  
  770.         It's even more easier when you shift your values of 8 bits.
  771.  
  772.         The 80X88 architecture allows you to split your regs in two
  773.  
  774.         8-bits parts. So if you've got your shifted value in AX,
  775.  
  776.         the integer approximation will be contained in AH.
  777.  
  778.         If you work with 16 bits values, for ex. in AX, your shifted
  779.  
  780.         val should be in EAX, so that the extended part contains the
  781.  
  782.         integer.(You can even work with 24 bits values, easy to implement
  783.  
  784.         when smartly using the SHLD/SHRD 386 instr.)
  785.  
  786.  
  787.  
  788.         b)- single bytes suckz
  789.  
  790.         ----------------------
  791.  
  792.  
  793.         All the main-loops examples I wrote only write one byte at each loop.
  794.  
  795.         It's much more efficient -when possible- to write two bytes (also
  796.  
  797.         called a word huhu!) at the same time.
  798.  
  799.         For example, here's the new Gouraud main loop :
  800.  
  801.         (5 inst. for two pixels!)
  802.  
  803.  
  804.         SHR     ECX,1
  805.  
  806.         @@:
  807.  
  808.         MOV     AL,DH
  809.  
  810.         ADD     EDX,EBP
  811.  
  812.         MOV     AH,DH
  813.  
  814.         STOSW
  815.  
  816.         ADD     EDX,EBP
  817.  
  818.         LOOP    @B
  819.  
  820.  
  821.         But warning ! This only works when you are writing at even offsets.
  822.  
  823.         Otherwise it won't speed up much, because when the CPU write a word on
  824.  
  825.         a byte border, it's as slow as writing two bytes 'manually'.
  826.  
  827.         So you'll have to check - before entering the loop - the parity
  828.  
  829.         of your first offset, first write one byte if it's odd, and the same
  830.  
  831.         when the loop is finished...
  832.  
  833.  
  834.         c)- about the 'loop' instruction
  835.  
  836.         --------------------------------
  837.  
  838.  
  839.         A word about the 'loop' instruction: I used it for clarity in my codes,
  840.  
  841.         but the fastest method for looping is the following:
  842.  
  843.  
  844.         instead of:     use:
  845.  
  846.         LOOP @B         DEC     ECX
  847.  
  848.                         JNZ     @B
  849.  
  850.  
  851.         The result is the same but it works much more faster !
  852.  
  853.         (Perhaps no more on P5, ..must be verified..)
  854.  
  855.  
  856.         d)- unrolled loops
  857.  
  858.         ------------------
  859.  
  860.  
  861.         The last tip is fine but the real fastest method for looping
  862.  
  863.         is ... not to loop !
  864.  
  865.         Don't you guess ?
  866.  
  867.         The trick is to 'unroll' your loop, I mean when you know the
  868.  
  869.         maximum number of times you may loop (usually 320 for a scanline ,
  870.  
  871.         let's say MAX) you write all the instruction one after one.
  872.  
  873.         When you enter your loop just jump at the offset LABEL+(MAX-ECX)*N,
  874.  
  875.         where N is the number of bytes of the instr. constituing your loop.
  876.  
  877.         Of coz you gotta use the 'REPEAT MAX (...) ENDM' macro-inst for
  878.  
  879.         writing the code, which induces a space loss, but it's really
  880.  
  881.         worth it.
  882.  
  883.         For the Gouraud:
  884.  
  885.  
  886.             JMP     ...         ; do it yourself, big boy !
  887.  
  888.  
  889.             REPEAT  320
  890.  
  891.             MOV     AL,DH       ; al = a shr 8
  892.  
  893.             ADD     DX,BP       ; a = a+((a2-a1)/(x2-x1))
  894.  
  895.             STOSB               ; es:[di] = a ; di = di+1
  896.  
  897.             ENDM
  898.  
  899.  
  900.         I said when talking about the texture mapping that it was possible
  901.  
  902.         to get rid of the var : just replace it by ECX which is not used
  903.  
  904.         anymore in the loop !
  905.  
  906.  
  907.                         ***** last minute *****
  908.  
  909.         It seems that the unrolled loops are not so efficient
  910.  
  911.         -if not less- on the new pipe-lined/"RISC" architecture of the Pentium..
  912.  
  913.         I am not a hardware freak, but so many people told me that
  914.  
  915.         I think I just have to believe it !
  916.  
  917.         It's your matter to know wich config your prodz should work on..
  918.  
  919.         And one way to know is TESTING.
  920.  
  921.  
  922.         e)- Z-buffer optimizations
  923.  
  924.         --------------------------
  925.  
  926.  
  927.         Yes, there are many !
  928.  
  929.         DO you know what a depth-sort is ?
  930.  
  931.         Well, it's just an implementation of the famous painter's algorithm:
  932.  
  933.         sort your polygons 'back-to-front', so that the nearest polys are
  934.  
  935.         recovering the furthest.
  936.  
  937.         For Z-buffer, just reverse : sort your polys 'front-to-back',
  938.  
  939.         so that -with a bit of luck- you just write the necessary pixels
  940.  
  941.         on the screen, and not the one which are going to be recovered.
  942.  
  943.  
  944.         John De Goes - creditz ! - told me some other trickz too:
  945.  
  946.         f.e:
  947.  
  948.         - you normally don't have to clear your Z-buffer every frame
  949.  
  950.         - in some special cases, you don't have to test every pixel
  951.  
  952.           on your scanline
  953.  
  954.         - You should be careful too on the Pentium branch-prediction
  955.  
  956.           chip(see 'last-minute' above): if most of the pixel of the
  957.  
  958.           poly will be written,execute the jump only if the current
  959.  
  960.           point is not written..
  961.  
  962.         - I heard talking about 'fuzzy' algorithms wich may be helpful
  963.  
  964.           (just heard..)
  965.  
  966.  
  967.         (see 'Zbuffinf.txt', kewl doc)
  968.  
  969.  
  970.        ┌────────────────────┐
  971.  
  972.        │6)- conclusion words│
  973.  
  974.        └────────────────────┘
  975.  
  976.  
  977.         I hope this doc will be helpful for beginners in 3d coding.
  978.  
  979.         It's the kind of help I would have appreciated when I was
  980.  
  981.         beginning one year ago.
  982.  
  983.         It perhaps seems a bit confused and the level of each part
  984.  
  985.         may be variable, but I didn't write it in one time, so
  986.  
  987.         if some explanations are not clear, don't hesitate to ask me..
  988.  
  989.         (Sorry for the bad english. I speak french, so be indulgent..)
  990.  
  991.  
  992.         I still have much to do in 3d coding:
  993.  
  994.         - implement a TRUE texture-mapping algo,
  995.  
  996.           not a linear distorsion.
  997.  
  998.         - I will probably releaze a txt about Phong shading,
  999.  
  1000.           including a (more or less) efficient implementation.
  1001.  
  1002.         - BSP trees and/or Z-buffer for a 3d virtual world.
  1003.  
  1004.         - The use of extended VESA/SVGA graphic modes such as
  1005.  
  1006.           Hi-color or 8bits-Hi-rez modes.
  1007.  
  1008.         - Pentium optimizations trix.
  1009.  
  1010.         any help is appreciated..!
  1011.  
  1012.  
  1013.        ┌──────────────────────────┐
  1014.  
  1015.        │7)- Credits and greetingz │
  1016.  
  1017.        └──────────────────────────┘
  1018.  
  1019.  
  1020.         Doc written by :
  1021.  
  1022.         ----------------
  1023.  
  1024.                             KARMA    [ Tfl/TdV = The Flamoots/The Dark Vision ]
  1025.  
  1026.                             (Jean Cardinal)
  1027.  
  1028.         CONTACT ME !!
  1029.  
  1030.         for anything: discussion,advices,remarks,flaming,collaboration...
  1031.  
  1032.         E-mail:
  1033.  
  1034.                             jcardin@is1.ulb.ac.be
  1035.  
  1036.  
  1037.         Thanx &/or greetingz to:
  1038.  
  1039.         ------------------------
  1040.  
  1041.  
  1042.                             MORFLAME        [TfL/TdV]
  1043.  
  1044.                                 -we gonna do good work together!
  1045.  
  1046.  
  1047.                             JOHN DE GOES    [on Compuserve]
  1048.  
  1049.                                 -Cool docs !
  1050.  
  1051.  
  1052.                             ALL THE MEMBS OF MY CREW :
  1053.  
  1054.                                     type one,sam,cybersurfer,
  1055.  
  1056.                                     fred,bismarck,gopi,fly,zoltan,Rod...
  1057.  
  1058.  
  1059.                             IMPHOBIA
  1060.  
  1061.                                 -'nice' is the word
  1062.  
  1063.  
  1064.                             and everyone I forgot...
  1065.  
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.  
  1092.  
  1093.